package com.yunke.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yunke.common.log.BusinessLog;
import com.yunke.common.result.YunkeResult;
import com.yunke.common.security.YunkeSecurityUtil;
import com.yunke.dto.YunkeCreateRechargeDto;
import com.yunke.dto.YunkeWithdrawalDto;
import com.yunke.entity.YunkeAmountLog;
import com.yunke.entity.YunkeRechargeOrder;
import com.yunke.entity.YunkeWithdrawal;
import com.yunke.service.YunkePayService;
import com.yunke.vo.YunkeBalanceVo;
import com.yunke.vo.YunkeRechargeConfigVo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;

import java.math.BigDecimal;
import java.util.Map;

/**
 * 云科支付系统控制器
 * 
 * @author yunke
 * @since 2024-01-01
 */
@Slf4j
@RestController
@RequestMapping("/api/pay")
@RequiredArgsConstructor
@Validated
@Tag(name = "支付系统", description = "充值、提现、余额支付等功能")
public class YunkePayController {

    private final YunkePayService payService;

    /**
     * 获取充值配置
     */
    @GetMapping("/rechargeConfig")
    @Operation(summary = "获取充值配置", description = "获取充值相关配置信息")
    @BusinessLog(value = "获取充值配置")
    public YunkeResult<YunkeRechargeConfigVo> getRechargeConfig() {
        YunkeRechargeConfigVo config = payService.getRechargeConfig();
        return YunkeResult.success(config);
    }

    /**
     * 创建充值订单
     */
    @PostMapping("/createRecharge")
    @Operation(summary = "创建充值订单", description = "创建用户充值订单")
    @BusinessLog(value = "创建充值订单", params = "amount,payType")
    public YunkeResult<YunkeRechargeOrder> createRecharge(@Valid @RequestBody YunkeCreateRechargeDto dto) {
        YunkeRechargeOrder order = payService.createRechargeOrder(dto);
        return YunkeResult.success(order);
    }

    /**
     * 查询充值状态
     */
    @GetMapping("/rechargeStatus")
    @Operation(summary = "查询充值状态", description = "查询充值订单状态")
    @BusinessLog(value = "查询充值状态", params = "orderNo")
    public YunkeResult<Map<String, Object>> getRechargeStatus(
            @Parameter(description = "订单号") @NotBlank @RequestParam String orderNo) {
        Map<String, Object> status = payService.getRechargeStatus(orderNo);
        return YunkeResult.success(status);
    }

    /**
     * 获取用户余额信息
     */
    @GetMapping("/balance")
    @Operation(summary = "获取用户余额信息", description = "获取当前用户的余额详情")
    @BusinessLog(value = "获取用户余额信息")
    public YunkeResult<YunkeBalanceVo> getUserBalance() {
        Long userId = YunkeSecurityUtil.getCurrentUserId();
        YunkeBalanceVo balance = payService.getUserBalance(userId);
        return YunkeResult.success(balance);
    }

    /**
     * 获取资金流水
     */
    @GetMapping("/amountLog")
    @Operation(summary = "获取资金流水", description = "获取用户资金变动流水记录")
    @BusinessLog(value = "获取资金流水")
    public YunkeResult<IPage<YunkeAmountLog>> getAmountLog(
            @Parameter(description = "交易类型") @RequestParam(required = false) Integer type,
            @Parameter(description = "页码") @RequestParam(defaultValue = "1") Integer pageNum,
            @Parameter(description = "页大小") @RequestParam(defaultValue = "10") Integer pageSize) {
        Long userId = YunkeSecurityUtil.getCurrentUserId();
        IPage<YunkeAmountLog> logs = payService.getAmountLog(userId, type, pageNum, pageSize);
        return YunkeResult.success(logs);
    }

    /**
     * 申请提现
     */
    @PostMapping("/withdrawal")
    @Operation(summary = "申请提现", description = "用户申请资金提现")
    @BusinessLog(value = "申请提现", params = "amount,withdrawalType")
    public YunkeResult<YunkeWithdrawal> applyWithdrawal(@Valid @RequestBody YunkeWithdrawalDto dto) {
        YunkeWithdrawal withdrawal = payService.applyWithdrawal(dto);
        return YunkeResult.success(withdrawal);
    }

    /**
     * 获取提现记录
     */
    @GetMapping("/withdrawalList")
    @Operation(summary = "获取提现记录", description = "获取用户提现申请记录")
    @BusinessLog(value = "获取提现记录")
    public YunkeResult<IPage<YunkeWithdrawal>> getWithdrawalList(
            @Parameter(description = "页码") @RequestParam(defaultValue = "1") Integer pageNum,
            @Parameter(description = "页大小") @RequestParam(defaultValue = "10") Integer pageSize) {
        Long userId = YunkeSecurityUtil.getCurrentUserId();
        IPage<YunkeWithdrawal> withdrawals = payService.getWithdrawalList(userId, pageNum, pageSize);
        return YunkeResult.success(withdrawals);
    }

    /**
     * 余额支付
     */
    @PostMapping("/balancePay")
    @Operation(summary = "余额支付", description = "使用账户余额进行支付")
    @BusinessLog(value = "余额支付", params = "amount,orderNo")
    public YunkeResult<Boolean> balancePay(
            @Parameter(description = "支付金额") @NotNull @RequestParam BigDecimal amount,
            @Parameter(description = "订单号") @NotBlank @RequestParam String orderNo,
            @Parameter(description = "支付密码") @NotBlank @RequestParam String payPassword,
            @Parameter(description = "支付标题") @NotBlank @RequestParam String title,
            @Parameter(description = "支付描述") @RequestParam(required = false) String description) {
        Long userId = YunkeSecurityUtil.getCurrentUserId();
        boolean result = payService.balancePay(userId, amount, orderNo, payPassword, title, description);
        return YunkeResult.success(result);
    }

    /**
     * 设置支付密码
     */
    @PostMapping("/setPayPassword")
    @Operation(summary = "设置支付密码", description = "设置用户支付密码")
    @BusinessLog(value = "设置支付密码")
    public YunkeResult<Boolean> setPayPassword(
            @Parameter(description = "支付密码") @NotBlank @RequestParam String payPassword,
            @Parameter(description = "短信验证码") @NotBlank @RequestParam String smsCode) {
        Long userId = YunkeSecurityUtil.getCurrentUserId();
        boolean result = payService.setPayPassword(userId, payPassword, smsCode);
        return YunkeResult.success(result);
    }

    /**
     * 修改支付密码
     */
    @PostMapping("/changePayPassword")
    @Operation(summary = "修改支付密码", description = "修改用户支付密码")
    @BusinessLog(value = "修改支付密码")
    public YunkeResult<Boolean> changePayPassword(
            @Parameter(description = "旧支付密码") @NotBlank @RequestParam String oldPayPassword,
            @Parameter(description = "新支付密码") @NotBlank @RequestParam String newPayPassword) {
        Long userId = YunkeSecurityUtil.getCurrentUserId();
        boolean result = payService.changePayPassword(userId, oldPayPassword, newPayPassword);
        return YunkeResult.success(result);
    }

    /**
     * 收支统计
     */
    @GetMapping("/statistics")
    @Operation(summary = "收支统计", description = "获取用户收支统计数据")
    @BusinessLog(value = "收支统计")
    public YunkeResult<Map<String, Object>> getPaymentStatistics(
            @Parameter(description = "开始时间") @RequestParam(required = false) Long startTime,
            @Parameter(description = "结束时间") @RequestParam(required = false) Long endTime) {
        Long userId = YunkeSecurityUtil.getCurrentUserId();
        Map<String, Object> statistics = payService.getPaymentStatistics(userId, startTime, endTime);
        return YunkeResult.success(statistics);
    }

    /**
     * 微信支付回调
     */
    @PostMapping("/wechatCallback")
    @Operation(summary = "微信支付回调", description = "微信支付异步通知回调")
    public String handleWechatCallback(@RequestBody String notifyData) {
        return payService.handleWechatCallback(notifyData);
    }

    /**
     * 支付宝支付回调
     */
    @PostMapping("/alipayCallback")
    @Operation(summary = "支付宝支付回调", description = "支付宝支付异步通知回调")
    public String handleAlipayCallback(@RequestParam Map<String, String> notifyData) {
        return payService.handleAlipayCallback(notifyData);
    }
} 